/**
 *
 */
package com.lehecai.core.lottery.fetcher.lotterydraw.impl.worker;

import com.lehecai.core.lottery.LotteryType;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDraw;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDrawPrizeItem;
import com.lehecai.core.util.CharsetConstant;
import com.lehecai.core.util.CoreDateUtils;
import com.lehecai.core.util.CoreFetcherUtils;
import org.apache.commons.lang.StringUtils;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.CssSelectorNodeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;


/**
 * 全国开奖页面网易彩票通用抓取页面实现类
 * @author sushi
 */
public class CountryLotteryDrawFetchWorker163 extends AbstractLotteryDrawFetchWorker {

    private static final Map<LotteryType, Integer> lotteryTypeNodeMap = new HashMap<LotteryType, Integer>();

    private static final String URL_DEFAULT = "http://caipiao.163.com/award/";

    protected String siteName = "T_163";

    protected String lotteryScope = "全国开奖";

    public final String DATE_FORMAT = "yyyy-MM-dd HH:mm"; // 网易开奖格式

    public static Map<LotteryType, String> historyUrlMap = new HashMap<LotteryType, String>();

    static {

        //不同彩种对应的解析节点(用于在开奖页面取得当前彩期)
        historyUrlMap.put(LotteryType.SSQ, "http://caipiao.163.com/award/ssq/");
        historyUrlMap.put(LotteryType.DLT, "http://caipiao.163.com/award/dlt/");
    }

    public CountryLotteryDrawFetchWorker163(LotteryType lotteryType) {
        super(lotteryType);
    }

    @Override
    public LotteryDraw fetchResult(String phase) {
        return this.fetchResultDetail(phase);
    }

    @Override
    public LotteryDraw fetchResultDetail(String phase) {
        LotteryType lotteryType = this.getLotteryType();
        String url = historyUrlMap.get(lotteryType);
        String pageInfo = "列表页面" + url;
        String logHeader = "==" + lotteryScope + "==" + siteName + "==" + pageInfo + "==抓取==" + getLotteryType().getName() + "==";
        String fetchUrl = null;
        if (phase == null || phase.isEmpty()) {// 无彩期的情况，先获取当前期
            String data = CoreFetcherUtils.URLGet(url, null, CharsetConstant.CHARSET_GBK);
            if (data == null || data.indexOf("404 Not Found") > 0) {
                logger.error("data is null or 404 Not Found");
                return null;
            }
            Parser parser = Parser.createParser(data, CharsetConstant.CHARSET_UTF8);
            NodeFilter cssFilter = new CssSelectorNodeFilter("span[id='date_no']");
            try {
                NodeList nodeList = parser.extractAllNodesThatMatch(cssFilter);
                String text = nodeList.elementAt(0).toPlainTextString();
                phase = text;
            } catch (ParserException e) {
                logger.error("未获得大乐透当前彩期信息！");
                return null;
            }

        }

        fetchUrl = this.getResultDetailUrl(phase);
        if (StringUtils.isEmpty(fetchUrl)) {
            logger.error("==详细页面==抓取=={}==期号：{}==详细地址不存在，返回null", lotteryType.getName(), phase);
            return null;
        }

        String openTime = "";
        String openResult = "";
        String prizePool = "";
        String saleValue = "";
        LotteryDraw lotteryDraw = null;
        List<LotteryDrawPrizeItem> resultDetail = new ArrayList<LotteryDrawPrizeItem>();
        LotteryDrawPrizeItem lotteryDrawPrizeItem = null;
        try {
            String data = CoreFetcherUtils.URLGet(fetchUrl, null, CharsetConstant.CHARSET_GBK);
            if (StringUtils.isEmpty(data)) {
                logger.error("data is null or 404 Not Found, url={}", fetchUrl);
                return null;
            }
            //开始解析详细数据
            Parser parser = Parser.createParser(data, CharsetConstant.CHARSET_UTF8);
            CssSelectorNodeFilter cssSelectorNodeFilter = new CssSelectorNodeFilter("div[class='search_zj_left']");
            NodeList nodeList = parser.extractAllNodesThatMatch(cssSelectorNodeFilter);
            Node node = nodeList.elementAt(0);
            NodeList nodeList1 = node.getChildren().extractAllNodesThatMatch(new TagNameFilter("p"));
            Node node1 = nodeList1.elementAt(0);
            NodeList spans = node1.getChildren().extractAllNodesThatMatch(new TagNameFilter("span"));
            Date date = CoreDateUtils.parseDate(spans.elementAt(0).toPlainTextString(), DATE_FORMAT);
            openTime = CoreDateUtils.formatDate(date, CoreDateUtils.DATE);
            saleValue = spans.elementAt(1).toPlainTextString();
            DecimalFormat df = new DecimalFormat("#");
            df.setRoundingMode(RoundingMode.FLOOR);
            Double prizeD = Double.parseDouble(spans.elementAt(2).toPlainTextString());
            prizePool = df.format(prizeD);
            // 解析红篮球
            Node detailNode = nodeList1.elementAt(1);
            NodeList redList = detailNode.getChildren().extractAllNodesThatMatch(new CssSelectorNodeFilter("span[class='red_ball']"));
            List<String> list = new ArrayList<String>();
            for (Node n : redList.toNodeArray()) {
                list.add(n.toPlainTextString());
            }
            NodeList blueList = detailNode.getChildren().extractAllNodesThatMatch(new CssSelectorNodeFilter("span[class='blue_ball']"));
            for (Node n : blueList.toNodeArray()) {
                list.add(n.toPlainTextString());
            }
            openResult = StringUtils.join(list, ",");// 组成开奖结果
            // 奖金详情
            CssSelectorNodeFilter cssSelectorNodeFilter1 = new CssSelectorNodeFilter("table[class=\"table2\"]");
            Parser par = Parser.createParser(data, CharsetConstant.CHARSET_UTF8);
            NodeList list1 = par.extractAllNodesThatMatch(cssSelectorNodeFilter1);
            Node node2 = list1.elementAt(0);
            NodeList tr = node2.getChildren().extractAllNodesThatMatch(new TagNameFilter("tr"));
            Node[] nodes = tr.toNodeArray();
            for (Node n : nodes) {
                if (n.toPlainTextString().trim().contains("奖项")) {
                    continue;
                }
                lotteryDrawPrizeItem = new LotteryDrawPrizeItem();
                NodeList td = n.getChildren().extractAllNodesThatMatch(new TagNameFilter("td"));
                if (td.size() == 3) {// 加奖的情况
                    if (lotteryType == LotteryType.DLT) {
                        lotteryDrawPrizeItem.setName(resultDetail.get(resultDetail.size() - 1).getName() + td.elementAt(0).toPlainTextString());
                    } else {
                        lotteryDrawPrizeItem.setName(td.elementAt(0).toPlainTextString());
                    }
                    lotteryDrawPrizeItem.setWinningCount(td.elementAt(1).toPlainTextString());
                    lotteryDrawPrizeItem.setPrizeAmount(td.elementAt(2).toPlainTextString());
                } else if (td.size() == 4) {
                    lotteryDrawPrizeItem.setName(td.elementAt(0).toPlainTextString());
                    lotteryDrawPrizeItem.setWinningCount(td.elementAt(2).toPlainTextString());
                    lotteryDrawPrizeItem.setPrizeAmount(td.elementAt(3).toPlainTextString());
                }
                resultDetail.add(lotteryDrawPrizeItem);
            }
        } catch (Exception e) {
            logger.error(logHeader + "数据解析错误==" + e.getMessage(), e);
            return null;
        }

        lotteryDraw = new LotteryDraw();
        lotteryDraw.setJackpot(prizePool);
        lotteryDraw.setLotteryType(lotteryType);
        lotteryDraw.setPhase(phase);
        lotteryDraw.setVolumeOfSales(saleValue);
        lotteryDraw.setTimeDraw(openTime);
        lotteryDraw.setResult(openResult);
        lotteryDraw.setResultDetail(resultDetail);
        return lotteryDraw;
    }

    @Override
    protected String getResultDetailUrl(String phase) {
        if (phase == null || phase.isEmpty()) return null;
        return historyUrlMap.get(this.getLotteryType()) + phase + ".html";
    }

    @Override
    protected String getResultUrl(String phase) {
        return null;
    }
}
